/*
 * URL: http://code.google.com/p/nagatsuki-accounting-lib/
 */
/**
 * $Id: DateNoUtil.java 108 2009-07-27 05:08:33Z tanaka.akira.2006 $
 */
package com.googlecode.nagatsuki.accountinglib.util;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.math.NumberUtils;

import com.googlecode.nagatsuki.accountinglib.exception.IllegalDateNoException;

/**
 * 取引番号ユーティリティ
 * <p>
 * 取引番号とは、"yyyyMMdd-#" な形式の仕訳番号です。 <br>
 * 仕訳帳などで仕訳のユニークキーとして利用されます。
 * </p>
 *
 * @author tanaka.akira.2006
 *
 */
public final class DateNoUtil {

	private static SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");

	/**
	 * 次の取引番号を返します。
	 *
	 * @param dateNo
	 *            取引番号 e.g. "20090101-10"
	 * @return 次の取引番号 e.g. "20090101-11"
	 * @throws IllegalDateNoException
	 */
	public static final String nextDateNo(final String dateNo)
			throws IllegalDateNoException {
		validate(dateNo);
		String[] arr = dateNo.split("-");
		String date = arr[0];
		int no = Integer.parseInt(arr[1]);
		return date + "-" + (no + 1);
	}

	/**
	 * 取引番号からYMD日付部分を文字列で返します。
	 *
	 * @param dateNo
	 * @return YMD日付
	 * @throws IllegalDateNoException
	 */
	public static final String getDateStr(final String dateNo)
			throws IllegalDateNoException {
		validate(dateNo);
		String[] arr = dateNo.split("-");
		return arr[0];
	}

	/**
	 * 取引番号からYMD日付部分を日付型で返します。
	 *
	 * @param dateNo
	 * @return YMD日付
	 * @throws IllegalDateNoException
	 * @throws ParseException
	 */
	public static final Date getDate(final String dateNo)
			throws IllegalDateNoException, ParseException {
		validate(dateNo);
		String[] arr = dateNo.split("-");
		synchronized (sdf) {
			return sdf.parse(arr[0]);
		}
	}

	/**
	 * 取引番号から連番部分を int で返します。
	 *
	 * @param dateNo
	 * @return 連番部分
	 * @throws IllegalDateNoException
	 */
	public static final int getNo(final String dateNo)
			throws IllegalDateNoException {
		validate(dateNo);
		String[] arr = dateNo.split("-");
		return Integer.parseInt(arr[1]);
	}

	/**
	 * 取引番号検証
	 *
	 * @param dateNo
	 * @throws IllegalDateNoException
	 */
	public static final void validate(final String dateNo)
			throws IllegalDateNoException {
		if (StringUtils.isEmpty(dateNo)) {
			throw new NullPointerException("dateNo is empty.");
		}
		String[] arr = dateNo.split("-");
		if (arr.length != 2) {
			throw new IllegalDateNoException(
					"取引番号が不正です。正しいフォーマットは、'yyyyMMdd-#' です。");
		}
		if (!NumberUtils.isNumber(arr[1])) {
			throw new IllegalDateNoException("取引番号が不正です。連番は数値である必要があります。");
		}
	}
}
